package com.gitee.wsl.io.channel.packet

import com.gitee.wsl.api.Closeable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class Packet<T>(
    @SerialName("t")
    val type: Int = 0,
    @SerialName("i")
    val id: String,
    @SerialName("m")
    val messageId: String,
    @SerialName("e")
    val endpoint: String,
    @SerialName("d")
    val data: T
) {
    val input: Boolean get() = (type and 1) != 0
    val binary: Boolean get() = (type and 2) != 0
    val startBinary: Boolean get() = (type and 4) != 0

    constructor(
        input: Boolean = false,
        binary: Boolean = false,
        startBinary: Boolean = false,
        id: String,
        messageId: String,
        endpoint: String,
        data: T
    ) : this(
        (if (input) 1 else 0) or
                (if (binary) 2 else 0) or
                (if (startBinary) 4 else 0),
        id,
        messageId,
        endpoint,
        data
    )
}

internal interface PacketChannel<T> : Closeable {
    suspend fun sendLocked(packet: Packet<T>)
    suspend fun receiveLocked(): Packet<T>
}
